package tcm.com.gistone.controller;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.tools.ant.util.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import tcm.com.gistone.database.config.GetBySqlMapper;
import tcm.com.gistone.database.entity.User;
import tcm.com.gistone.database.entity.UserType;
import tcm.com.gistone.database.mapper.UserMapper;
import tcm.com.gistone.database.mapper.UserTypeMapper;
import tcm.com.gistone.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @Author:renqiang
 * @Param:
 * @Description:账号管理
 * @Date:14:50 2017/7/14
 */
@RestController
@RequestMapping("user")
@Transactional
public class UserController {
    private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ClientUtil.class);
    @Autowired
    UserMapper userMapper;
    @Autowired
    EmailUtils emailUtils;
    @Autowired
    UserTypeMapper userTypeMapper;
    @Autowired
    GetBySqlMapper gm;
    @Autowired
    UserTypeMapper utm;

    @Value("${app.frontend}")
    public String frontend;


    /*激活账号*/
    @RequestMapping(value = "/activate", method = RequestMethod.POST)
    public EdatResult activate(HttpServletRequest request,
                               HttpServletResponse response) {

        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            String email = data.getString("email");
            String token = data.getString("token");
            Calendar c = Calendar.getInstance();
            // 现在的时间(单位：毫秒)
            long curtime = c.getTimeInMillis();
            User user = userMapper.selectByStatusAndTokenAndEmail(0, token, email);
            if (user != null) {
                long token_exptime = Long.parseLong(user.getTokenExptime());
                // 如果激活码过期
                if (curtime > token_exptime) {
                    // 如果过期就先删除相应用户信息，然后重新发送邮件
                    userMapper.deleteByPrimaryKey(user.getId());
                    return EdatResult.build(1, "链接失效,请重新注册!");
                } else {
                    // 更新用户激活状态
                    user.setStatus(1);
                    userMapper.updateByPrimaryKey(user);
                    return EdatResult.build(0, "激活成功!", user);
                }
            } else {
                return EdatResult.build(1, "链接失效,请重新注册!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "失败");
        }
    }

    /*通过邮箱发送忘记密码邮件 @Author:wangfan*/
    @Transactional
    @ResponseBody
    @RequestMapping(value = "forget", method = RequestMethod.POST)
    public EdatResult forget(HttpServletRequest request,
                             HttpServletResponse response) {

        try {
            ClientUtil.SetCharsetAndHeader(request, response);

            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            String email = data.getString("email");


            User user = userMapper.selectByEmail(email);


            if (null == user) {
                return EdatResult.build(1, "不存在该邮箱");
            }


            //	String password = data.getString("password");


            Calendar c = Calendar.getInstance();
            // 现在的时间(单位：毫秒)
            long time = c.getTimeInMillis();

            long tokenExptime = time + 1000 * 60 * 60 * 24;
            user.setTokenExptime(Long.toString(tokenExptime));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String href = frontend + "/resetPassword.html?email=" + email + "&token=" + user.getToken();
            StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;\">您好，" + user.getLoginName() + "<br/>"
                    + "<br/><br/>"
                    + "<br/>请点击下面链接重新修改密码，24小时有效，否则重新注册账号，链接只能使用一次，请尽快修改密码！<br/><br/>");
            sb.append("<a href='" + href + "'>" + href + "</a>");
            sb.append("<br/>如果以上链接无法点击，请把上面网页地址复制到浏览器地址栏中打开,或选中链接，右键选择新窗口打开<br/><br/><br/>"
                    + "<p>中医古籍文献知识库</p><br/>" + sdf.format(new Date()) + "</div></div>");

            // 发送邮件
            if (emailUtils.sendHtmlMail("中医古籍文献知识库- 修改密码", sb.toString(), email)) {
                return EdatResult.ok(user);
            } else {
                return EdatResult.build(1, "邮件发送失败");
            }


        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "发生错误");
        }
    }


    /*充值密码@Author:wangfan*/
    @Transactional
    @ResponseBody
    @RequestMapping(value = "resetPassword", method = RequestMethod.POST)
    public EdatResult resetPassword(HttpServletRequest request,
                                    HttpServletResponse response) {

        try {
            ClientUtil.SetCharsetAndHeader(request, response);

            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            int flag = data.getInt("flag");
            String password = data.getString("password");
            String rpassword = data.getString("rpassword");
            String email = data.getString("email");
            if (password.length() < 6 && password.length() > 16) {
                return EdatResult.build(1, "密码不符合格式!长度必须大于等于6，且小于等于16");
            }
            if (rpassword.length() < 6 && rpassword.length() > 16) {
                return EdatResult.build(1, "密码不符合格式!长度必须大于等于6，且小于等于16");
            }
            if (!password.equals(rpassword)) {
                return EdatResult.build(1, "两次密码不一致");
            }
            User user = null;
            if (flag == 1) {

                String token = data.getString("token");

                user = userMapper.selectByStatusAndTokenAndEmail(1, token, email);

                if (null == user) {
                    return EdatResult.build(1, "无效的token，不能重置密码！");
                }


            } else {
                String opassword = data.getString("opassword");
                user = userMapper.selectByEmail(email);
                if (null == user) {
                    return EdatResult.build(1, "用户不存在！");
                }


                if (!user.getUserPwd().equals(Tool.md5(opassword))) {
                    return EdatResult.build(1, "旧密码不正确");
                }

            }


            user.setUserPwd(Tool.md5(password));

            userMapper.updateByPrimaryKey(user);
            return EdatResult.ok(user);

        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "发生错误");
        }
    }


    /*创建注册用户@Author:wangfan*/
    @Transactional
    @ResponseBody
    @RequestMapping(value = "createRegisterUser", method = RequestMethod.POST)
    public EdatResult createRegisterUser(HttpServletRequest request,
                                         HttpServletResponse response) {

        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            String loginName = data.getString("loginName");
            String userName = data.getString("userName");
            String password = data.getString("password");
            String rpassword = data.getString("rpassword");
            String tel = data.getString("tel");
            String mail = data.getString("mail");
            String organization = data.getString("organization");
            String position = data.getString("position");
            int level = data.getInt("level");

            User user1 = userMapper.selectOne(loginName);
            if (null != user1) {
                return EdatResult.build(1, "登录名重复");
            }
            user1 = userMapper.selectByEmail(mail);
            if (null != user1) {
                return EdatResult.build(1, "邮箱重复");
            }

            if (!password.equals(rpassword)) {
                return EdatResult.build(1, "两次密码不一致");
            }
            //	String password = data.getString("password");

            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateNowStr = sdf.format(d);
            if (null == userName || userName == "") {
                return EdatResult.build(1, "请输入正确格式的用户名");
            }

            User user = new User();
            user.setLoginName(loginName);
            user.setUserType(level);
            user.setUserName(userName);
            user.setUserPwd(Tool.md5(password));
            user.setTel(tel);
            user.setEmail(mail);
            user.setCreateTime(dateNowStr);
            user.setStatus(0);
            user.setOrganization(organization);
            user.setPosition(position);
            Calendar c = Calendar.getInstance();
            // 现在的时间(单位：毫秒)
            long time = c.getTimeInMillis();
            String token = Tool.md5(mail + password + time);
            user.setToken(token);

            String href = frontend + "?email=" + mail + "&token=" + token;
            long tokenExptime = time + 1000 * 60 * 60 * 24;
            user.setTokenExptime(Long.toString(tokenExptime));
            StringBuffer sb = new StringBuffer("<div style=\"padding:24px 20px;\">您好，" + userName + "<br/>"
                    + "<br/><br/>"
                    + "<br/>请点击下面链接激活账号，24小时有效，否则重新注册账号，链接只能使用一次，请尽快激活并填写信息！<br/><br/>");
            sb.append("<a href='" + href + "'>" + href + "</a>");
            sb.append("<br/>如果以上链接无法点击，请把上面网页地址复制到浏览器地址栏中打开,或选中链接，右键选择新窗口打开<br/><br/><br/>"
                    + "<p>中医古籍文献知识库</p><br/>" + sdf.format(new Date()) + "</div></div>");

            // 发送邮件
            if (emailUtils.sendHtmlMail("中医古籍文献知识库- 账户激活", sb.toString(), mail)) {
                userMapper.insert(user);
                return EdatResult.ok(user);
            } else {
                return EdatResult.build(1, "通知邮件发送失败");
            }


        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "创建账号失败");
        }
    }


    /*创建用户*/
    @ResponseBody
    @RequestMapping(value = "createUser", method = RequestMethod.POST)
    public EdatResult createUser(HttpServletRequest request,
                                 HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            String loginName = data.getString("loginName");/*登录账号*/
            String userName = data.getString("userName");/*用户名称*/
            User user1 = userMapper.selectOne(loginName);
            if (null != user1) {
                return EdatResult.build(1, "登录名重复");
            }
            String tel = data.getString("tel");
            String mail = data.getString("mail");
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateNowStr = sdf.format(d);
            if (null == userName || userName == "") {
                return EdatResult.build(1, "请输入正确格式的用户名");
            }
            int level = data.getInt("level");
            User user = new User();
            user.setLoginName(loginName);
            user.setUserType(level);
            user.setUserName(userName);
            user.setUserPwd(Tool.md5("123456"));
            user.setTel(tel);
            user.setEmail(mail);
            user.setCreateTime(dateNowStr);
            user.setStatus(1);
            userMapper.insert(user);
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "创建账号失败");
        }
    }

    /*获取用户类型*/
    @RequestMapping(value = "getUserTypes")
    public EdatResult getUserTypes(HttpServletRequest request,
                                   HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            List<UserType> list = userTypeMapper.selectAll();
            return EdatResult.ok(list);
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "查询失败");
        }
    }

    /*更新角色信息*/
    @RequestMapping(value = "updateRole")
    public EdatResult updatePermission(HttpServletRequest request,
                                       HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            long id = data.getLong("id");
            String name = data.getString("name");/*角色名*/
            String permission = data.getString("per");/*权限*/
            UserType userType = utm.selectByPrimaryKey(id);
            if (name.equals(userType.getTypeName())) {
                userType.setPermission(permission);
                utm.updateByPrimaryKey(userType);
            } else {
                UserType userType1 = utm.selectByName(name);
                if (null == userType1) {
                    userType.setTypeName(name);
                    userType.setPermission(permission);
                    utm.updateByPrimaryKey(userType);
                } else {
                    return EdatResult.build(1, "角色名称冲突");
                }
            }
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "修改失败");
        }
    }

    /*添加角色*/
    @RequestMapping(value = "addRole")
    public EdatResult addRole(HttpServletRequest request,
                              HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            String name = data.getString("name");/*角色名称*/
            String permission = data.getString("per");/*权限*/
            UserType userType = utm.selectByName(name);
            if (null != userType) {
                return EdatResult.build(1, "名称重复");
            } else {
                UserType userType1 = new UserType();
                userType1.setTypeName(name);
                userType1.setPermission(permission);
                utm.insert(userType1);
                return EdatResult.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "添加失败");
        }
    }

    /*删除角色*/
    @RequestMapping(value = "deleteRole")
    public EdatResult deleteRole(HttpServletRequest request,
                                 HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            long id = data.getLong("id");
            String sql = "select * from tb_user where user_type = " + id;
            List<Map> list = gm.findRecords(sql);
            if (list.size() > 0) {
                return EdatResult.build(1, "存在该角色账号，无法删除该角色");
            } else {
                utm.deleteByPrimaryKey(id);
                return EdatResult.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "删除失败");
        }
    }

    /*更改用户信息*/
    @RequestMapping(value = "updateUser", method = RequestMethod.POST)
    public EdatResult updateteUser(HttpServletRequest request,
                                   HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            long id = data.getLong("id");
            int per = data.getInt("per");/*角色*/
            String userName = data.getString("userName");
            //	String password = data.getString("password");
            String tel = data.getString("tel");
            String email = data.getString("email");
            User user = userMapper.selectByPrimaryKey(id);
            user.setUserType(per);
            user.setUserName(userName);
            user.setTel(tel);
            user.setEmail(email);
            userMapper.updateByPrimaryKey(user);
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "修改失败");
        }

    }

    /*查询用户*/
    @ResponseBody
    @RequestMapping("getAllUser")
    public Map getAllUser(HttpServletRequest request,
                          HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            int pageNumber = Integer.parseInt(request
                    .getParameter("pageNumber"));
            int pageSize = Integer.parseInt(request
                    .getParameter("pageSize"));
            String keyWord = request.getParameter("keyWord");/*登录名或用户名关键词*/
            keyWord =  StringUtils.replace(keyWord,"_","\\_");
            keyWord =  StringUtils.replace(keyWord,"%","\\%");
            String sql = "select id,login_name, user_name,tel,email,user_type,create_time,permi_time from tb_user where status != 0 ";
            String sql2="";
            if(!keyWord.equals("")){
                sql2+=" and ( user_name like '%" +keyWord + "%' or login_name like '%" + keyWord + "%')";
            }
            sql+=sql2+"  limit " + pageNumber + "," + pageSize;
            List<Map> result = gm.findRecords(sql);
            String sql1 = "select count(*) as total from tb_user where status != 0"+sql2;
            int total = gm.findrows(sql1);
            Map map = new HashMap();
            map.put("total", total);
            map.put("rows", result);
            map.put("page", pageNumber / pageSize);
            logger.info("查询成功");
            return map;
        } catch (Exception e) {
            logger.warn("查询失败");
            e.printStackTrace();
            return null;
        }
    }

    /*删除/禁用用户*/
    @RequestMapping(value = "deleteUser", method = RequestMethod.POST)
    public EdatResult deleteUser(HttpServletRequest request,
                                 HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            JSONArray array = data.getJSONArray("userId");
            for (int i = 0; i < array.size(); i++) {
                long userId = array.getLong(i);
                String sql = "update tb_user set status = 0 where id = " + userId;
                gm.update(sql);
            }
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "删除失败");
        }
    }

    /*恢复用户*/
    @RequestMapping(value = "recoverUser", method = RequestMethod.POST)
    public EdatResult recoverUser(HttpServletRequest request,
                                  HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            JSONArray userIds = data.getJSONArray("userIds");
            for (int i = 0; i < userIds.size(); i++) {
                long id = userIds.getLong(i);
                String sql = "update tb_user set status = 1 where user_id = " + id;
                gm.update(sql);
            }
            return EdatResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "操作失败");
        }
    }

    /**
     * 用户登录
     */
    @RequestMapping(value = "login", method = RequestMethod.POST)
    @ResponseBody
    public EdatResult login(
            HttpServletRequest request, HttpServletResponse response) {
        try {
            // 设置跨域
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request
                    .getParameter("data"));
            String loginName = data.getString("loginName");
            String userPwd = data.getString("userPwd");

            /*校验验证码*/
            /*String result_verifyCode = request.getSession().getAttribute("randomString")
                    .toString().toUpperCase();
            String user_verifyCode =data.getString("verify");
            if(null == user_verifyCode || !result_verifyCode.equalsIgnoreCase(user_verifyCode)){
                logger.info("验证码错误");
                return  EdatResult.build(1008, "验证码错误！");
            }
*/

            /*//定义账号的正则表达式
            String regEx = "^[a-zA-Z]+[a-zA-Z0-9_]{5,14}$";
            //进行参数判断
            if (!RegUtil.CheckParameter(loginName, "String", regEx, false)) {
                LogUtil.getLogger().error("UserController  账号不存在!");
                return EdatResult.build(1003, "账号不存在!");
            }

            //进行参数判断
            if (!RegUtil.CheckParameter(userPwd, "String", null, false)) {
                LogUtil.getLogger().error("UserController  密码不正确!");
                return EdatResult.build(1003, "密码不正确!");
            }*/
            //查看当前账号是否存在
            User user = userMapper.selectOne(loginName);

//            //查看当前账号密码是否正确
//            user = userMapper.selectByLoginNameAndUserPwd(loginName, Tool.md5(userPwd));

            //判断如果存在
            if (null != user) {
                if (user.getStatus() == 0) {
                    return EdatResult.build(100, "账号未激活，请前往注册邮箱进行激活后使用");
                }
                if(!user.getUserPwd().equals(Tool.md5(userPwd))){
                    return EdatResult.build(1001, "密码不正确");
                }
                HttpSession session = request.getSession();
                session.setAttribute("user", user);
                //添加Log
                LogUtil.getLogger().info("UserController  登录成功！");
                //返回结果
                return EdatResult.build(0, "登录成功", user);
            } else {
                return EdatResult.build(1001, "账号不存在");
            }

        } catch (Exception e) {
            LogUtil.getLogger().error("UserController 用户登录异常！", e);
            return EdatResult.build(1001, "用户登录异常！");
        }
    }

    /**
     * 获取session信息
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("get_sessionInfo")
    public EdatResult get_sessionInfo(HttpServletRequest
                                              request, HttpServletResponse response) throws Exception {
        try {
            // 设置跨域
            ClientUtil.SetCharsetAndHeader(request, response);
            HttpSession session = request.getSession();
            //验证session不为空
            if (session.getAttribute("user") != null) {
                //取出用户信息
                User userInfo = (User) session.getAttribute("user");
                UserType userType =userTypeMapper.selectByPrimaryKey((long)userInfo.getUserType());
                LogUtil.getLogger().info("UserController  获取Session成功！");
                //将信息添加到结果集
                Map m =new HashMap();
                m.put("userInfo",userInfo);
                m.put("userType",userType);
                return EdatResult.ok(m);

            } else {
                LogUtil.getLogger().error("UserController  没有Session信息!");
                return EdatResult.build(1002, "没有Session信息!");
            }
        } catch (Exception e) {
            LogUtil.getLogger().error("UserController 获取Session异常！", e);
            return EdatResult.build(1001, "获取Session异常!");
        }

    }


    /**
     * 销毁session
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping("loginOut")
    public EdatResult loginOut(HttpServletRequest request, HttpServletResponse
            response) throws Exception {

        try {
            // 设置跨域
            ClientUtil.SetCharsetAndHeader(request, response);
            HttpSession session = request.getSession();
            //销毁Session中的信息
            session.invalidate();
            LogUtil.getLogger().info("UserController 用户退出成功！");
            return EdatResult.ok(1);
        } catch (Exception e) {
            LogUtil.getLogger().error("UserController 用户退出异常！", e);
            return EdatResult.build(1001, "UserController 用户退出异常！");
        }
    }
}
